// This File is part of the "nyaqt" Project
// 
// Copyright  2009 sometmes@gmail.com
// All rights reserved
// 
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using nyaqt.Plugins;

namespace nyaqt
{
    public partial class NewConnectionForm : Form
    {
        ConnectWorkItem _connectWorkItem = new ConnectWorkItem();
        ConnectWorkItem _testWorkItem = new ConnectWorkItem();
        EnabledState _enabledState = new EnabledState();
        ISimpleConnectionEdit _editor = null;
        Size _dessignMinimumSize;
        BackgroundWorker2 _connectWorker;
        BackgroundWorker2 _testConnectWorker;

        protected override void OnMouseWheel(MouseEventArgs e)
        {
            Control target = connectButton;
            Cursor.Position = this.PointToScreen(new Point(target.Bounds.Left + (int)(target.Width * (1 - (1.0 / 5))), target.Bounds.Top + (target.Height / 2)));
        }

        public ConnectionInfo Connection
        {
            get { return _connectWorkItem.Connection; }
            set
            {
                if (value != _connectWorkItem.Connection)
                {
                    _connectWorkItem.Connection = value;
                    connectionBindingSource.DataSource = value;
                }
            }
        }

        public bool ConnectTwoTimes
        {
            get { return _connectWorkItem.ConnectTwoTimes; }
            set { _connectWorkItem.ConnectTwoTimes = value; }
        }

        public IDbConnection SecondConnection
        {
            get { return _connectWorkItem.SecondConnection; }
            set { _connectWorkItem.SecondConnection = value; }
        }

        public NewConnectionForm()
        {
            InitializeComponent();
            _connectWorker = new BackgroundWorker2();
            //_connectWorker.WorkerReportsProgress = false;
            //_connectWorker.WorkerSupportsCancellation = true;
            _connectWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.connectWorker_DoWork);
            _connectWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.connectWorker_RunWorkerCompleted);

            this._testConnectWorker = new BackgroundWorker2();
            //this.testConnectWorker.WorkerSupportsCancellation = true;
            //testConnectWorker.WorkerReportsProgress = false;
            this._testConnectWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.testConnectWorker_DoWork);
            this._testConnectWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.testconnectWorker_RunWorkerCompleted);

        }

        private void NewConnectionForm_Load(object sender, EventArgs e)
        {
            _dessignMinimumSize = this.MinimumSize;
            if (this.Connection == null)
            {
                ConnectionInfo cn = My.Settings.LastConnection;
                if (cn == null)
                    cn = new ConnectionInfo();
                this.Connection = cn;
            }
            else
            {
                //connectionBindingSource.DataSource = connectionBindingSource.DataSource;
            }
            if (_connectWorkItem.Connection.Current != null)
            {
                changeProvider1.Enabled = false;
                changeProvider2.Enabled = false;
            }
            ToggleConnectionStringDisplay(My.Settings.ShowConnectionStringOnConnectDialog);
        }

        private void ToggleConnectionStringDisplay(bool display)
        {
            My.Settings.ShowConnectionStringOnConnectDialog = display;
            if (display) //Show Connection string TextBox
            {
                if (!connectionStringTextBox.Visible)
                {
                    this.MinimumSize = new Size(this.MinimumSize.Width, this.MinimumSize.Height + connectionStringTextBox.Height);
                    //this.Height += connectionStringTextBox.Height;
                    configurePanel.Height -= connectionStringTextBox.Height;
                }
                showConnectionStringButton.Image = My.Resources.DLMIN;
                connectionStringTextBox.Visible = true;
            }
            else //Hide Connection string TextBox
            {
                if (connectionStringTextBox.Visible)
                {
                    connectionStringTextBox.Visible = false;
                    this.MinimumSize = new Size(this.MinimumSize.Width, this.MinimumSize.Height - connectionStringTextBox.Height);
                    this.Height -= connectionStringTextBox.Height;
                    configurePanel.Height += connectionStringTextBox.Height;
                }
                showConnectionStringButton.Image = My.Resources.DLMAX;
                connectionStringTextBox.Visible = false;
            }
        }

        void ShowEditorControl(string invariantName, int version)
        {
            simpleEditGroupBox.Controls.Clear();
            if (!string.IsNullOrEmpty(invariantName))
            {
                _editor = SimpleConnectionEditorPlugin.CreateInstance(invariantName);
                UserControl editor = _editor as UserControl;
                editor.Location = new Point(6, 15);
                simpleEditGroupBox.Controls.Add(editor);
                this.MinimumSize = new Size(0,0); // _dessignMinimumSize;
                int xdiff = simpleEditGroupBox.Width - (2 * 6) - editor.Width;
                this.Width -= xdiff;
                int ydiff = simpleEditGroupBox.Height - (2 * 15) - editor.Height;
                this.Height -= ydiff;
                this.MinimumSize = this.Size;
                editor.Dock = DockStyle.Fill;
                //editor.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
                _editor.EditConnection(_connectWorkItem.Connection.Factory.DbProviderFactory, _connectWorkItem.Connection, BuildRecentStringBuilderList(invariantName, version));
            }
        }

        List<nyaqt.Plugins.NyaqtConnectionStringBuilder> BuildRecentStringBuilderList(string invariantName, int version)
        {
            List<nyaqt.Plugins.NyaqtConnectionStringBuilder> list = new List<nyaqt.Plugins.NyaqtConnectionStringBuilder>();
            if (My.Settings.RecentConnections.Contains(invariantName + ";" + version))
            {
                ConnectionInfoList il = My.Settings.RecentConnections[invariantName + ";" + version];
                foreach (ConnectionInfo info in il.Connections)
                {
                    nyaqt.Plugins.NyaqtConnectionStringBuilder copy = info.ConnectionStringBuilder.Copy();
                    copy.Password = info.Password;
                    list.Add(copy);
                }
            }
            return list;
        }

        private void advancedButton_Click(object sender, EventArgs e)
        {
            ConnectionStringBuilderForm f = new ConnectionStringBuilderForm();
            f.ConnectionStringBuilder = _connectWorkItem.Connection.Factory.DbProviderFactory.CreateConnectionStringBuilder();
            f.ConnectionStringBuilder.ConnectionString = _connectWorkItem.Connection.ConnectionStringWithPwd;
            f.Text = _connectWorkItem.Connection.ProviderName + " connection string properties.";
            if (f.ShowDialog() == DialogResult.OK)
            {
                nyaqt.Plugins.NyaqtConnectionStringBuilder csb = _connectWorkItem.Connection.ConnectionStringBuilder.Copy();
                csb.ConnectionString = f.ConnectionStringBuilder.ConnectionString;
                _connectWorkItem.Connection.UpdateConnectionString(csb);
                testConnection.Enabled = !string.IsNullOrEmpty(_connectWorkItem.Connection.ConnectionString);
            }
        }

        private void acceptButton_Click(object sender, EventArgs e)
        {
            _enabledState = WinForms.DisableBut(cancelButton);
            cancelButton.DialogResult = DialogResult.None;
            _connectWorker.RunWorkerAsync();
        }

        private void testConnection_Click(object sender, EventArgs e)
        {
            _enabledState = WinForms.DisableBut(cancelButton);
            cancelButton.DialogResult = DialogResult.None;
            _testConnectWorker.RunWorkerAsync();
        }

        private void testConnectWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            _testWorkItem.Connection = _connectWorkItem.Connection.Copy();
            _testWorkItem.Connection.Factory = new NyaqtProviderFactory(_connectWorkItem.Connection.ProviderInvariantName, _connectWorkItem.Connection.Version > 1);
            _testWorkItem.ConnectTwoTimes = false;
            _testWorkItem.DoWork(sender, e);

            ConnectResult r = e.Result as ConnectResult;
            if (r.Success)
                r.Message = SR.TestConnectSuccess;
            else
                r.Message = SR.TestConnectFail + "\r\n\r\n" + r.Message;
        }

        private void testconnectWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            WinForms.DisableRestore(_enabledState);
            ConnectResult r = e.Result as ConnectResult;
            MessageBox.Show(r.Message, SR.TestConnectTitle);
            cancelButton.DialogResult = DialogResult.Cancel;
        }

        private void cancelButton_Click(object sender, EventArgs e)
        {
            if (_testConnectWorker.IsBusy)
                _testConnectWorker.Abort();
            if (_connectWorker.IsBusy)
                _connectWorker.Abort();
            //_connectWorkItem.Connection.Current = _connectWorkItem.Connection.CreateConnection();
            WinForms.DisableRestore(_enabledState);
            cancelButton.DialogResult = DialogResult.Cancel;
        }

        private void connectWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            _connectWorkItem.DoWork(sender, e);

            ConnectResult r = e.Result as ConnectResult;
            if (r.Success)
                r.Message = SR.ConnectSuccess;
            else
                r.Message = SR.ConnectFail + "\r\n\r\n" + r.Message;
        }

        private void connectWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            WinForms.DisableRestore(_enabledState);
            ConnectResult r = e.Result as ConnectResult;
            cancelButton.DialogResult = DialogResult.Cancel;
            if (r.Success == false)
            {
                MessageBox.Show(r.Message, SR.ConnectTitle);
                _connectWorkItem.Connection.Current = null;
            }
            else
            {
                My.Settings.LastConnection = _connectWorkItem.Connection.Copy();
                My.Settings.RecentConnections.RegisterConnection(My.Settings.LastConnection);
                this.DialogResult = DialogResult.OK;
            }
        }

        private void showConnectionStringButton_Click(object sender, EventArgs e)
        {
            ToggleConnectionStringDisplay(!connectionStringTextBox.Visible);
        }

        private void connectionBindingSource_CurrentItemChanged(object sender, EventArgs e)
        {
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //_worker.Connection.ConnectionString += ";test=1";
        }

        private void connectionBindingSource_ListChanged(object sender, ListChangedEventArgs e)
        {
            if (_connectWorkItem.Connection == null) return;
            string name = "None";
            if (e.ListChangedType == ListChangedType.Reset)
                name = "ALL";
            else if ((e.ListChangedType == ListChangedType.ItemChanged || e.ListChangedType == ListChangedType.PropertyDescriptorChanged) && e.PropertyDescriptor != null)
                name = e.PropertyDescriptor.Name;

            if (name == "ProviderInvariantName" || name == "ALL")
            {
                if (!string.IsNullOrEmpty(_connectWorkItem.Connection.ProviderInvariantName))
                {
                    _connectWorkItem.Connection.Factory = new NyaqtProviderFactory(_connectWorkItem.Connection.ProviderInvariantName, _connectWorkItem.Connection.Version > 1);

                    if (_connectWorkItem.Connection.Version > 1)
                    {
                        provider2Textbox.Text = _connectWorkItem.Connection.ProviderName;
                        provider1Textbox.Text = "";
                    }
                    else
                    {
                        provider2Textbox.Text = "";
                        provider1Textbox.Text = _connectWorkItem.Connection.ProviderName;
                    }
                }
                ShowEditorControl(_connectWorkItem.Connection.ProviderInvariantName, _connectWorkItem.Connection.Version);
            }
            else if (name == "ConnectionString" || name == "ALL")
            {
                testConnection.Enabled = (!string.IsNullOrEmpty(_connectWorkItem.Connection.ConnectionString)) && (!(_connectWorkItem.Connection.Factory == null));
                advancedButton.Enabled = !(_connectWorkItem.Connection.Factory == null);
                if (_editor != null && _connectWorkItem.Connection.Factory != null)
                    _editor.EditConnection(_connectWorkItem.Connection.Factory.DbProviderFactory, this.Connection, BuildRecentStringBuilderList(_connectWorkItem.Connection.ProviderInvariantName, _connectWorkItem.Connection.Version));
            }
        }

        private void changeProvider2_Click(object sender, EventArgs e)
        {
            ChangeProviderForm f = new ChangeProviderForm();
            f.Version = 2;
            f.SelectedConnection = Connection;
            if (f.ShowDialog() == DialogResult.OK)
            {
                this.Connection = f.SelectedConnection;
            }
        }

        private void changeProvider1_Click(object sender, EventArgs e)
        {
            //ConnectionInfo cn = new ConnectionInfo();
            //cn.SupportsProviderFactory = false;
            //cn.ProviderInvariantName = "Sybase.Data.AseClient;1";
            //cn.ProviderName = "SybaseAseProvider";
            //cn.ConnectionString = @"Server Name=ES3175SYBT.europe.apci.com;Port=5000;Initial Catalog=TR;CharSet=iso_1;Application Name=APMedicalDirect;Enlist=0;Pooling=False;;User ID='impromptu';Password='COGNOS'";
            //this.Connection = cn;

            ChangeProviderForm f = new ChangeProviderForm();
            f.Version = 1;
            f.SelectedConnection = Connection;
            if (f.ShowDialog() == DialogResult.OK)
            {
                this.Connection = f.SelectedConnection;
            }
        }

        private void NewConnectionForm_Shown(object sender, EventArgs e)
        {
            this.ActiveControl = provider2Textbox;
        }

    }
}
































